﻿using ExcelParser.Writer;
using System;
using System.Reflection;

namespace ExcelParser.CodeGen
{
    public class ObjectField : ExcelField
    {
        public ObjectField(string name, string desc) : base(name + "Object", name, desc) { }

        public override int MaxChildrenCount { get { return int.MaxValue; } }
        public override void GenClass(CodeWriter writer)
        {
            base.GenClass(writer);
            writer.WriteComment(Desc + "类型");
            writer.WriteLine("[Serializable]");
            writer.WriteLine("public class {0}", Type);
            writer.WriteLine("{{");
            writer.Indent++;
            for (int i = 0; i < m_children.Count; i++)
            {
                m_children[i].GenCode(writer);
            }
            writer.Indent--;
            writer.WriteLine("}}");
        }

        public override void GenCode(CodeWriter writer)
        {
            base.GenCode(writer);
            string fieldName = "m_" + Name.Substring(0, 1).ToLower() + Name.Substring(1);
            writer.WriteLine("private {0} {1};", writer.ConvertType(Type), fieldName);
            writer.WriteLine("public {0} {1}", writer.ConvertType(Type), Name);
            writer.WriteLine("{{");
            writer.Indent++;
            writer.WriteLine("get {{ return {0}; }}", fieldName);
            writer.WriteLine("set {{ {0} = value; }}", fieldName);
            writer.Indent--;
            writer.WriteLine("}}");
        }

        public override void ParseValue(CodeWriter writer, object obj, PropertyInfo propertyInfo, MethodInfo methodInfo, Type fieldType, string value)
        {
            object objInstance = Activator.CreateInstance(fieldType);
            Type objInstanceType = objInstance.GetType();
            string[] values = value.Split(',');
            for (int i = 0; i < values.Length; i++)
            {
                ExcelField child = m_children[i];
                PropertyInfo objPropertyInfo = objInstanceType.GetProperty(child.Name);
                child.ParseValue(writer, objInstance, objPropertyInfo, null, objPropertyInfo.PropertyType, values[i]);
            }
            if (propertyInfo != null)
            {
                propertyInfo.SetValue(obj, objInstance, null);
            }
            if (methodInfo != null)
            {
                methodInfo.Invoke(obj, new object[] { objInstance });
            }
        }
    }
}